<!DOCTYPE html>



  


<html class="theme-next pisces use-motion" lang="zh-Hans">




<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/zhu/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/zhu/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/zhu/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/zhu/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/zhu/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/zhu/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/zhu/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="网络," />










<meta property="og:type" content="article">
<meta property="og:title" content="HTTP协议">
<meta property="og:url" content="https://gitee-zct.gitee.io/zhu/2021-04-16/http%E7%AC%94%E8%AE%B0%20-%20%E5%89%AF%E6%9C%AC/index.html">
<meta property="og:site_name" content="zhu">
<meta property="og:locale">
<meta property="og:image" content="https://img-blog.csdn.net/20180412212226327">
<meta property="og:image" content="https://img-blog.csdn.net/20180412212422475">
<meta property="og:image" content="https://img-blog.csdn.net/20180413203934426">
<meta property="og:image" content="file:///D:/2418049194/Image/C2C/687208D9EC8BA421B7800033AE1860F5.jpg">
<meta property="og:image" content="file:///D:/2418049194/Image/C2C/4AC205A75DBEEE49D6C3891A34C21CE1.jpg">
<meta property="og:image" content="file:///D:/2418049194/Image/C2C/812CDCACB3B35D032D948D8C2980701A.jpg">
<meta property="article:published_time" content="2021-04-16T07:35:21.530Z">
<meta property="article:modified_time" content="2021-04-16T07:37:28.109Z">
<meta property="article:author" content="zhu">
<meta property="article:tag" content="网络">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://img-blog.csdn.net/20180412212226327">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '',
    scheme: 'Pisces',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://gitee-zct.gitee.io/zhu/2021-04-16/http笔记 - 副本/"/>





  <title>HTTP协议 | zhu</title>
  








<meta name="generator" content="Hexo 5.4.0"></head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>


    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/zhu/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">zhu</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle">我的小世界</p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/zhu/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/zhu/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/zhu/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/zhu/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/zhu/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-sitemap">
          <a href="/zhu/sitemap.xml" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-sitemap"></i> <br />
            
            站点地图
          </a>
        </li>
      

      
        <li class="menu-item menu-item-search">
          
            <a href="javascript:;" class="popup-trigger">
          
            
              <i class="menu-item-icon fa fa-search fa-fw"></i> <br />
            
            搜索
          </a>
        </li>
      
    </ul>
  

  
    <div class="site-search">
      
  <div class="popup search-popup local-search-popup">
  <div class="local-search-header clearfix">
    <span class="search-icon">
      <i class="fa fa-search"></i>
    </span>
    <span class="popup-btn-close">
      <i class="fa fa-times-circle"></i>
    </span>
    <div class="local-search-input-wrapper">
      <input autocomplete="off"
             placeholder="搜索..." spellcheck="false"
             type="text" id="local-search-input">
    </div>
  </div>
  <div id="local-search-result"></div>
</div>



    </div>
  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://gitee-zct.gitee.io/zhu/zhu/2021-04-16/http%E7%AC%94%E8%AE%B0%20-%20%E5%89%AF%E6%9C%AC/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/zhu/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="zhu">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">HTTP协议</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2021-04-16T15:35:21+08:00">
                2021-04-16
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/zhu/categories/%E5%AD%A6%E4%B9%A0/" itemprop="url" rel="index">
                    <span itemprop="name">学习</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          
            <span class="post-meta-divider">|</span>
            <span class="page-pv">本文阅读量
            <span class="busuanzi-value" id="busuanzi_value_page_pv" ></span>
            </span>
          

          
            <div class="post-wordcount">
              
                
                <span class="post-meta-item-icon">
                  <i class="fa fa-file-word-o"></i>
                </span>
                
                  <span class="post-meta-item-text">字数统计&#58;</span>
                
                <span title="字数统计">
                  6.8k
                </span>
              

              
                <span class="post-meta-divider">|</span>
              

              
                <span class="post-meta-item-icon">
                  <i class="fa fa-clock-o"></i>
                </span>
                
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                
                <span title="阅读时长">
                  30
                </span>
              
            </div>
          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <h2 id=""><a href="#" class="headerlink" title=""></a></h2><p><em><span id="more"></span></em></p>
<h1 id="HTTP协议"><a href="#HTTP协议" class="headerlink" title="HTTP协议"></a>HTTP协议</h1><h4 id="http协议简介："><a href="#http协议简介：" class="headerlink" title="http协议简介："></a>http协议简介：</h4><p>​                                (HyperText Transfer Protocal)超文本传输协议</p>
<p>​                              （HyperText Markup Language/HTML）超文本标记语言</p>
<p>​                                协议规则：内容本身</p>
<p>​                                1传输明文内容，安全性较差</p>
<p>​                                2无状态协议</p>
<p>​                                3应用层协议，标准化协议1.1版本</p>
<p>​                                HTTPWatch</p>
<p>HTTP响应：常用字段理解</p>
<p>HTTP-Session{    保存在服务器端</p>
<p>​    http无状态</p>
<p>​    Session ID</p>
<p>}</p>
<p>Cookie 保存在客户端的</p>
<p>Cookie是由服务器端生成，发送给User-Agent,浏览器会将Cookie的key/value保存到某个目录下的文本文件内，下次请求同一网站时就发送该Cookie给服务器,</p>
<h3 id="Http协议"><a href="#Http协议" class="headerlink" title="Http协议"></a>Http协议</h3><p>Request Headers:</p>
<p>GET /s01/ser01?uname-zhangsan HTTP/1.1</p>
<p>​            问号后面是参数</p>
<p>http请求头的第一行,就是请求行（三部分组成：Get(请求方式)请求路径，HTTP/1.1(请求协议版本)）</p>
<p>后面的键值对，‘xxx=xxx’这些都是请求头</p>
<p>get请求没有请求正文，（get请求会把相关的参数全部跟在地址栏后面，）</p>
<p>post请求 的请求参数放在Form Data(请求体)</p>
<h3 id="http响应报文的组成"><a href="#http响应报文的组成" class="headerlink" title="http响应报文的组成"></a>http响应报文的组成</h3><p>http响应报文由响应行，响应头，响应体三部分组成。</p>
<p><img src="https://img-blog.csdn.net/20180412212226327" alt="img"></p>
<p>响应行主要包括</p>
<p>​    响应协议，这个与请求协议对应，比如http,</p>
<p>​    状态码200</p>
<p>​    状态码的描述OK</p>
<p>响应头就是一些常见的响应名对应的响应值</p>
<p>响应参数就是我们真正需要的从数据库中取出的数据</p>
<h3 id="常见的响应头属性"><a href="#常见的响应头属性" class="headerlink" title="常见的响应头属性"></a>常见的响应头属性</h3><p>下面是摘自<a target="_blank" rel="noopener" href="http://www.baidu.com和一个示例网站的请求头/">www.baidu.com和一个示例网站的请求头</a></p>
<p><img src="https://img-blog.csdn.net/20180412212422475" alt="img"></p>
<p><img src="https://img-blog.csdn.net/20180413203934426" alt="img"></p>
<p>(1) Accept-Ranges</p>
<p>​    表明服务器是否支持指定范围的请求，比如bytes,表明支持字节请求</p>
<p>(2) Access-Control-Allow-Origin</p>
<p>​    在服务器响应客户端的时候，如果设置Access-Control-Allow-Origin：* ，则允许所有域名的脚本访问该资源</p>
<p>Access-Control-Allow-Origin：<a target="_blank" rel="noopener" href="http://www.ppt.com/">http://www.ppt.com</a> ,则表示值允许特定的域名访问。</p>
<p>(3) Age</p>
<p>​    从原始服务器到代理缓存形成的估算时间，单位为秒。</p>
<p>(4) Cache-Control</p>
<p>​    告诉所有的缓存机制是否可以缓存，已经缓存的类型。cache-control : no-cache</p>
<p>(5) Connection</p>
<p>​     在http1.1中request和reponse  header中都有可能出现一个connection头字段，此header的含义是当client和server通信时对于长链接如何进行处理。在http1.1中，client和server都是默认对方支持长链接的，  如果client使用http1.1协议，但又不希望使用长链接，则需要在header中指明connection的值为close；如果server方也不想支持长链接，则在response中也需要明确说明connection的值为close。</p>
<p>(6)Content-Length</p>
<p>​    响应体的长度，web服务器返回消息正文的长度</p>
<p>(7) Content-Type</p>
<p>​    返回内容的MIME类型Content-Type ： text/html;charset=utf-8</p>
<p>(8) Date</p>
<p>​    原始服务器消息发出的时间</p>
<p>(9) Etag</p>
<p>​    请求变量的实体标签的当前值</p>
<p>(10) Expires</p>
<p>​    响应过期的时间</p>
<p>(11) Last-Modified</p>
<p>​    请求资源的最后修改时间</p>
<p>(12) Server</p>
<p>​    web服务器软件名称</p>
<p>​                                </p>
<p>GET没有请求体,</p>
<h2 id="ServletRequest中文的响应乱码"><a href="#ServletRequest中文的响应乱码" class="headerlink" title="ServletRequest中文的响应乱码"></a>ServletRequest中文的响应乱码</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.xxxx;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.servlet.Servlet;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.ServletException;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.ServletOutputStream;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.annotation.WebServlet;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServlet;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletRequest;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletResponse;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.io.PrintWriter;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *响应数据</span></span><br><span class="line"><span class="comment"> *      getWriter() 字符输出流--输出字符串</span></span><br><span class="line"><span class="comment"> *      getOutputStream（）字节输出流--输出任意类型的数据</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> *      两种不可同时使用，如果同时使用会报错</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@WebServlet(&quot;/s01&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Servlet01</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">service</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line"><span class="comment">//        //getWriter() 字符输出流--输出字符串</span></span><br><span class="line"><span class="comment">//        //获取字符输出流</span></span><br><span class="line"><span class="comment">//        PrintWriter writer=response.getWriter();</span></span><br><span class="line"><span class="comment">//        //输出数据</span></span><br><span class="line"><span class="comment">//        writer.write(&quot;hello&quot;);</span></span><br><span class="line"><span class="comment">//0-------不可以同时使用，上面必须先注释掉</span></span><br><span class="line">        <span class="comment">//getOutputStream（）字节输出流--输出任意类型的数据</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">//得到字节输出流</span></span><br><span class="line">        ServletOutputStream out=response.getOutputStream();</span><br><span class="line">        <span class="comment">//输出数据</span></span><br><span class="line">        out.write(<span class="string">&quot;asdh&quot;</span>.getBytes());</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *字符流响应数据</span></span><br><span class="line"><span class="comment"> * 乱码原因:</span></span><br><span class="line"><span class="comment"> *          对应getWriter()获取到的字符流，响应中文必定出现乱码，由于服务端在进行编码时默认使用“ISO-8859-1”格式的编码，该编码不自持中文</span></span><br><span class="line"><span class="comment"> *  乱码解决：</span></span><br><span class="line"><span class="comment"> *          1.设置服务端的编码格式</span></span><br><span class="line"><span class="comment"> *          response.setCharacterEncoding(&quot;UTF-8&quot;);</span></span><br><span class="line"><span class="comment"> *         2·设置客户端的编码格式和响应的MIME类型</span></span><br><span class="line"><span class="comment"> *         response.setHeader(&quot;content-type&quot;,&quot;text/html;chatset=UTF-8&quot;);</span></span><br><span class="line"><span class="comment"> *总结：设置客户端和服务端的编码支持中文，且保持一致</span></span><br><span class="line"><span class="comment">       同时设置客户端和服务端的方法</span></span><br><span class="line"><span class="comment">    response.setContentType(&quot;text/html;charset=UTF-8&quot;);</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@WebServlet(&quot;/s02&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Servlet02</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">service</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        <span class="comment">//设置服务端的编码格式</span></span><br><span class="line">       <span class="comment">// response.setCharacterEncoding(&quot;UTF-8&quot;);</span></span><br><span class="line">        <span class="comment">//设置客户端的编码格式和响应的MIME类型</span></span><br><span class="line">      <span class="comment">//  response.setHeader(&quot;content-type&quot;,&quot;text/html;chatset=UTF-8&quot;);</span></span><br><span class="line">        <span class="comment">//总结：设置客户端和服务端的编码支持中文，且保持一致</span></span><br><span class="line">        <span class="comment">//同时设置客户端和服务端的方法</span></span><br><span class="line">        response.setContentType(<span class="string">&quot;text/html;charset=UTF-8&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//getWriter() 字符输出流--输出字符串</span></span><br><span class="line">        <span class="comment">//获取字符输出流</span></span><br><span class="line">        PrintWriter writer=response.getWriter();</span><br><span class="line">        writer.write(<span class="string">&quot;&lt;h2&gt;你好&lt;/h2&gt;&quot;</span>);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *  字节流响应数据</span></span><br><span class="line"><span class="comment"> *  乱码问题</span></span><br><span class="line"><span class="comment"> *          对于getOutputStream()方式获取到的字符流，响应中文时，由于本身就是传输字节，所以此时可能传输字节，</span></span><br><span class="line"><span class="comment"> *          当服务端给的字节恰好和客户端使用的编码方式一致时则文本正确显示，否则出现乱码</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> *      response.setContentType(&quot;text/html;charset=UTF-8&quot;);</span></span><br><span class="line"><span class="comment"> **/</span></span><br><span class="line"><span class="meta">@WebServlet(&quot;/s03&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Servlet03</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">service</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        response.setContentType(<span class="string">&quot;text/html;charset=UTF-8&quot;</span>);</span><br><span class="line">        <span class="comment">//得到字节输出流</span></span><br><span class="line">        ServletOutputStream out=response.getOutputStream();</span><br><span class="line">        <span class="comment">//输出数据</span></span><br><span class="line">        out.write(<span class="string">&quot;&lt;h2&gt;你话&lt;/h2&gt;&quot;</span>.getBytes(<span class="string">&quot;UTF-8&quot;</span>));</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="重定向"><a href="#重定向" class="headerlink" title="重定向"></a>重定向</h2><p>重定向是一种服务器指导，客户端的行为。客户端发出第一个请求后，被服务器接收处理后，服务器会进行响应，在响应的同时，服务器会给客户端一个新的地址（下次请求的地址response.sendRedirect(url)）当客户端接收响应后,会里立刻，马上，自动根据服务器给的新地址发起第二个请求，服务器接收请求并作出响应，重定向完成。</p>
<p><img src="file:///D:\2418049194\Image\C2C\687208D9EC8BA421B7800033AE1860F5.jpg" alt="img"></p>
<p>==tomcat改为Updateresource就不用不断重启了==</p>
<h1 id="HTTP"><a href="#HTTP" class="headerlink" title="HTTP"></a>HTTP</h1><ul>
<li><p>概念：Hyper Text Transfer Protocal 超文本传输协议</p>
<ul>
<li>传输协议：定义了客户端和服务器端通信时，发送数据的格式</li>
<li>特点：<ol>
<li>基于TCP/IP的高级协议</li>
<li>HTTP的默认端口号是：80<pre><code>http ://ww w.baidu.cn:80
</code></pre>
</li>
<li>基于请求响应模型的：一次请求对应一次响应</li>
<li>无状态的：每次请求之间相互独立，不能相互交换数据</li>
</ol>
</li>
</ul>
<ul>
<li>历史版本<ul>
<li>1.0：每次请求响应建立新的连接</li>
<li>1.1：复用连接</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><strong>请求消息数据格式</strong></p>
<ol>
<li><p>请求行</p>
<pre><code>     请求方式    请求URL    请求协议/版本
     GET            login.html    HTTPP/1.1 
</code></pre>
</li>
</ol>
<p>   ​        <strong>请求方式</strong>：</p>
<p>   ​                HTTP有7种请求方式，常用有两种</p>
<p>   ​                        GET:</p>
<p>   ​                                get参数在请求行种（在url后）。<br>   ​                                get的请求的url长度是有限制的<br>   ​                                相对不太安全，显示在了url中</p>
<p>   ​                        POST:<br>   ​                                请求参数在请求体种<br>   ​                                请求的url长度没有限制<br>   ​        </p>
<ol start="2">
<li><p>请求头</p>
<p>​        请求头名称：请求头值</p>
<p>​        <strong>常见的请求头</strong></p>
<ul>
<li><p>User-Agent : 浏览器告诉服务器，我访问你使用的浏览器信息</p>
<pre><code>            可以在服务器端获取该头的信息，来解决兼容性问题
</code></pre>
<p>Accept : 告诉服务器我可解析数据格式</p>
<p>Referer : <a target="_blank" rel="noopener" href="http://localhost/login.html">http://localhost/login.html</a></p>
<pre><code>    告诉服务器，当前请求从哪里来
        作用：
                1防盗链
</code></pre>
<p>​                    2统计功能</p>
<p><img src="file:///D:\2418049194\Image\C2C\4AC205A75DBEEE49D6C3891A34C21CE1.jpg" alt="img"></p>
<p>Connection: keep-alive</p>
</li>
</ul>
</li>
<li><p>请求空行</p>
<pre><code> （  空行  ），就是用于分隔POST请求的请求头和请求体的
</code></pre>
</li>
<li><p>请求体（正文）</p>
<pre><code>   封装POST请求消息的 请求参数的（请求体）
</code></pre>
<p>字符串格式</p>
</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">GET &#x2F;login.html HTTP&#x2F;1.1------&gt;请求行</span><br><span class="line"></span><br><span class="line"> 				请求头↓</span><br><span class="line"> Host: localhost			</span><br><span class="line"> User-Agent: Mozilla&#x2F;5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko&#x2F;20100101 Firefox&#x2F;81.0</span><br><span class="line"> Accept: text&#x2F;html,application&#x2F;xhtml+xml,application&#x2F;xml;q&#x3D;0.9,image&#x2F;webp,*&#x2F;*;q&#x3D;0.8</span><br><span class="line"> Accept-Language: zh-CN,zh;q&#x3D;0.8,zh-TW;q&#x3D;0.7,zh-HK;q&#x3D;0.5,en-US;q&#x3D;0.3,en;q&#x3D;0.2</span><br><span class="line"> Accept-Encoding: gzip, deflate</span><br><span class="line"> Connection: keep-alive</span><br><span class="line"> Cookie: JSESSIONID&#x3D;03C5A1C8F189D7D8C395FEFAA95A91E1</span><br><span class="line"> Upgrade-Insecure-Requests: 1</span><br><span class="line"> （请求空行）</span><br></pre></td></tr></table></figure>



   <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">POST &#x2F;demo3 HTTP&#x2F;1.1---&gt;请求行</span><br><span class="line">			请求头↓</span><br><span class="line">Host: localhost</span><br><span class="line">User-Agent: Mozilla&#x2F;5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko&#x2F;20100101 Firefox&#x2F;81.0</span><br><span class="line">Accept: text&#x2F;html,application&#x2F;xhtml+xml,application&#x2F;xml;q&#x3D;0.9,image&#x2F;webp,*&#x2F;*;q&#x3D;0.8</span><br><span class="line">Accept-Language: zh-CN,zh;q&#x3D;0.8,zh-TW;q&#x3D;0.7,zh-HK;q&#x3D;0.5,en-US;q&#x3D;0.3,en;q&#x3D;0.2</span><br><span class="line">Accept-Encoding: gzip, deflate</span><br><span class="line">Content-Type: application&#x2F;x-www-form-urlencoded</span><br><span class="line">Content-Length: 11</span><br><span class="line">Origin: http:&#x2F;&#x2F;localhost</span><br><span class="line">Connection: keep-alive</span><br><span class="line">Referer: http:&#x2F;&#x2F;localhost&#x2F;login.html</span><br><span class="line">Cookie: JSESSIONID&#x3D;03C5A1C8F189D7D8C395FEFAA95A91E1</span><br><span class="line">Upgrade-Insecure-Requests: 1</span><br><span class="line">        （请求空行）</span><br><span class="line">username&#x3D;zhangsan----&gt;请求体</span><br></pre></td></tr></table></figure>

<p><strong>响应消息数据格式</strong></p>
<h2 id="Request："><a href="#Request：" class="headerlink" title="Request："></a>Request：</h2><ol>
<li><p>request对象和response对象的原理</p>
<pre><code>        ![img](file:///D:\2418049194\Image\C2C\1F881DC9273B0A7A03C3713525148CFC.jpg)
</code></pre>
<p>​            1。request和response是有服务器创建，我们使用而已<br>​            2。request是来获取请求消息，response是来设置响应消息<br>​            </p>
<p>2.request对象的继承体系结构：</p>
<pre><code>    ServletRequest                                               抽象类
                |  继承
    HttpServletRequest                                         抽象类
                |  实现
</code></pre>
<p>​        org.apache.catalina.connector.RequestFacade 类（tomcat）</p>
<p>​    </p>
<p>3.request功能</p>
<ol>
<li><p>获取请求消息</p>
<ol>
<li><p>获取请求行数据</p>
<ol>
<li><p>请求行的格式    </p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GET /day14/demo1?name=zhangsan  HTTP/1.1</span><br></pre></td></tr></table></figure>

<p>方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.</span> 获取请求方式：GET</span><br><span class="line">  	<span class="function">String <span class="title">getMethod</span><span class="params">()</span>                </span></span><br><span class="line"><span class="function"><span class="comment">//**2. 获取虚拟目录：/day14               </span></span></span><br><span class="line"><span class="function">  ​	String <span class="title">getContextPath</span><span class="params">()</span>              </span></span><br><span class="line"><span class="function"> 3. 获取Servlet路径：/demo1             </span></span><br><span class="line"><span class="function">  ​ String <span class="title">getServletPath</span><span class="params">()</span>              </span></span><br><span class="line"><span class="function">4. 获取GET方式的请求参数：name</span>=zhangsan               </span><br><span class="line">  ​ <span class="function">String <span class="title">getQueryString</span><span class="params">()</span>             </span></span><br><span class="line"><span class="function"><span class="comment">//**5. 获取URI:  /day14/demo1            </span></span></span><br><span class="line"><span class="function">   ​ String <span class="title">getRequestURI</span><span class="params">()</span>		/day14/demo1             </span></span><br><span class="line"><span class="function">   ​ String <span class="title">getRequestURL</span><span class="params">()</span>    http:||localhost/fay14/demo1</span></span><br><span class="line"><span class="function">        url:统一资源定位符：http:||localhost/fay14/demo1  红双喜乒乓球</span></span><br><span class="line"><span class="function">        uri:统一资源标识符：/day14/demo1                  乒乓球          </span></span><br><span class="line"><span class="function">6. 获取协议及版本：HTTP/1.1             </span></span><br><span class="line"><span class="function">   ​ String <span class="title">getProtacol</span><span class="params">()</span>              </span></span><br><span class="line"><span class="function">7. 获取客户机的IP地址          </span></span><br><span class="line"><span class="function">  ​	String <span class="title">getRemotAddr</span><span class="params">()</span> </span></span><br></pre></td></tr></table></figure>

<p>​          </p>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
<li><p>获取请求头数据</p>
<pre><code>  方法:
</code></pre>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">(​​​)<span class="function">String	<span class="title">getHeader</span><span class="params">(String name)</span>:通过请求头的名称获取请求头的值</span></span><br><span class="line"><span class="function">Enumeration&lt;String&gt; <span class="title">getHeaderName</span><span class="params">()</span>:获取所有请求头的名称</span></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@WebServlet(&quot;/RequestDemo2&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RequestDemo2</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doPost</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doGet</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        <span class="comment">//演示获取所有请求头数据</span></span><br><span class="line">        Enumeration&lt;String&gt; headerName=request.getHeaderNames();</span><br><span class="line">        <span class="comment">//遍历</span></span><br><span class="line">        <span class="keyword">while</span>(headerName.hasMoreElements())&#123;</span><br><span class="line">            String name=headerName.nextElement();</span><br><span class="line">            <span class="comment">//根据名称获取请求头的值</span></span><br><span class="line">            String value=request.getHeader(name);</span><br><span class="line">            System.out.println(name+<span class="string">&quot;----&quot;</span>+value);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ol>
<p>​           </p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@WebServlet(&quot;/RequestDemo2&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RequestDemo2</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doPost</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doGet</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        <span class="comment">//演示获取请求头</span></span><br><span class="line">        String agent = request.getHeader(<span class="string">&quot;user-agent&quot;</span>);</span><br><span class="line">        <span class="comment">//判断agent的浏览器版本</span></span><br><span class="line">        <span class="keyword">if</span>(agent.contains(<span class="string">&quot;Chrome&quot;</span>))&#123;</span><br><span class="line">            <span class="comment">//谷歌</span></span><br><span class="line">            System.out.println(<span class="string">&quot;谷歌来了&quot;</span>);</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span>(agent.contains(<span class="string">&quot;Firefox&quot;</span>))&#123;</span><br><span class="line">            <span class="comment">//火狐</span></span><br><span class="line">            System.out.println(<span class="string">&quot;火狐来了&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<ol start="3">
<li><p>获取请求体数据</p>
<p>​    请求体：只有POST请求方式有请求体，在请求体中封装了POST请求的请求参数</p>
<p>​    步骤：</p>
<ol>
<li><p>获取流对象</p>
<ol>
<li><p>BufferedReader getReader(): 获取字符输入流，操作字符数据（字符用次方法方便）<br>返回BufferedRead高效的带有缓冲区的</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doPost</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">    <span class="comment">//获取请求消息体</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">//1获取字符流</span></span><br><span class="line">    BufferedReader br = request.getReader();</span><br><span class="line">    <span class="comment">//2读取数据</span></span><br><span class="line">    String line=<span class="keyword">null</span>;</span><br><span class="line">    <span class="keyword">while</span> ((line=br.readLine())!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        System.out.println(line);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
<li><p>ServletInputStream getInputStream(): 获取字节输入流，可操作所有类型数据<br>在文件上传的地方详解。</p>
</li>
</ol>
</li>
<li><p>再从流对象获取数据</p>
</li>
</ol>
</li>
<li><p>其他功能:</p>
<ol>
<li><p>获取请求参数通用方式：</p>
<ol>
<li><p>```java</p>
<ol>
<li><p>String getParameter(String name);根据参数名称获取参数值                                      username=zhnagsan&amp;pwd=12</p>
<pre><code>            传username返回zhangsan
</code></pre>
</li>
<li><p>String[] getParameterValues(String name);根据参数名称获取参数值的数组                             hobby=xx&amp;hobby=game</p>
<pre><code>               多用于复选框
</code></pre>
</li>
<li><p>Enumeration<String> getParameterNames();获取所有请求参数名称</p>
</li>
<li><p>Map&lt;String,String[]&gt;获取所有参数的map集合</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">&#96;&#96;&#96;java</span><br><span class="line">&#x2F;&#x2F;例子</span><br><span class="line">&#x2F;&#x2F;1. String getParameter(String name);根据参数名称获取参数值 </span><br><span class="line">@WebServlet(&quot;&#x2F;Demo6&quot;)</span><br><span class="line">public class RequestDemo6 extends HttpServlet &#123;</span><br><span class="line">    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException &#123;</span><br><span class="line">        &#x2F;&#x2F;POST获取请求参数</span><br><span class="line">        String username &#x3D; request.getParameter(&quot;username&quot;);</span><br><span class="line">        System.out.println(&quot;POST&quot;);</span><br><span class="line">        System.out.println(username);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException &#123;</span><br><span class="line">        &#x2F;&#x2F;GET获取请求参数</span><br><span class="line">&#x2F;&#x2F;        String username &#x3D; request.getParameter(&quot;username&quot;);</span><br><span class="line">&#x2F;&#x2F;        System.out.println(&quot;GET&quot;);</span><br><span class="line">&#x2F;&#x2F;        System.out.println(username);</span><br><span class="line">        doPost(request,response);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@WebServlet(&quot;/Demo6&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RequestDemo6</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doPost</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        <span class="comment">//POST获取请求参数</span></span><br><span class="line">        String username = request.getParameter(<span class="string">&quot;username&quot;</span>);</span><br><span class="line">        String[] hobbies = request.getParameterValues(<span class="string">&quot;hobby&quot;</span>);</span><br><span class="line">        <span class="keyword">for</span>(String  hobby:hobbies)&#123;</span><br><span class="line">            System.out.println(hobby);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doGet</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        <span class="comment">//GET获取请求参数</span></span><br><span class="line">        doPost(request,response);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">Enumeration&lt;String&gt; parameterNames = request.getParameterNames();</span><br><span class="line"> <span class="keyword">while</span> (parameterNames.hasMoreElements())&#123;</span><br><span class="line">     String name=parameterNames.nextElement();</span><br><span class="line">    System.out.println(name);</span><br><span class="line"></span><br><span class="line">         String[] hobbiess = request.getParameterValues(name);</span><br><span class="line">         <span class="keyword">for</span>(String hobby:hobbiess) &#123;</span><br><span class="line">             System.out.println(hobby);</span><br><span class="line"></span><br><span class="line">         &#125;</span><br><span class="line">      System.out.println(<span class="string">&quot;------&quot;</span>);</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@WebServlet(&quot;/Demo6&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RequestDemo6</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doPost</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        <span class="comment">//获取所有参数map集合</span></span><br><span class="line">        Map&lt;String, String[]&gt; parameterMap = request.getParameterMap();</span><br><span class="line">        Set&lt;String&gt; keyset = parameterMap.keySet();</span><br><span class="line">        <span class="keyword">for</span>(String name:keyset)&#123;</span><br><span class="line">            <span class="comment">//根据key键获取值</span></span><br><span class="line">            String[] values = parameterMap.get(name);</span><br><span class="line">            System.out.println(name);</span><br><span class="line">            <span class="keyword">for</span> (String value:values)&#123;</span><br><span class="line">                System.out.println(value);</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println(<span class="string">&quot;-------&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doGet</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        doPost(request,response);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>中文乱码问题：</p>
<p>get方式：tomcat8已解决get中文乱码</p>
<p>post:会乱码</p>
<p>​        ==解决;在获取参数前设置请求request的编码：request.setCharacterEncoding(“UTF-8”);==</p>
<p>​        </p>
<p>​                </p>
</li>
</ol>
</li>
<li><p>请求转发：一种在==服务器内部==的资源跳转方式</p>
<p>步骤：</p>
<ol>
<li><p>通过request对象：RequestDispatcher getRequestDispatcher(String path)</p>
</li>
<li><p>使用RequestDispatcher对象来进行转发:</p>
<p>forward（ServletRequest request,ServletResponse response）;</p>
<table>
<thead>
<tr>
<th>v.</th>
<th>Dispatcher                                                                                                                                           派遣;                                                                                                                                                 调遣;</th>
</tr>
</thead>
<tbody><tr>
<td></td>
<td></td>
</tr>
</tbody></table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//RequestDispatcher requestDispatcher = request.getRequestDispatcher(&quot;/Demo9&quot;); //requestDispatcher.forward(request,response);</span></span><br><span class="line">        request.getRequestDispatcher(<span class="string">&quot;/Demo9&quot;</span>).forward(request,response);</span><br></pre></td></tr></table></figure>

<p><img src="file:///D:\2418049194\Image\C2C\812CDCACB3B35D032D948D8C2980701A.jpg" alt="img"></p>
<p>特点：</p>
<pre><code>    1. 浏览器的地址栏路径没有发生变化
    2. 只能转发到当前服务器内部的资源中。
                    3. 转发是一次请求
</code></pre>
</li>
</ol>
</li>
<li><p>共享数据：</p>
<p>​        域对象：一个有作用范围的数据，可以在范围内共享数据</p>
<p>​        request域：代表一次请求的范围，一般用于请求转发的多个资源中共享数据</p>
<p>​        方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> 	<span class="title">setAttribute</span><span class="params">(String name,Object obj)</span></span>;存储数据（Attribute属性）</span><br><span class="line"><span class="function">Object	<span class="title">getAttribute</span><span class="params">(String name )</span>通过键获取对象</span></span><br><span class="line"><span class="function"><span class="keyword">void</span>	<span class="title">removeAttribute</span><span class="params">(String name)</span>通过键移除键值对</span></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//request共享数据例子</span></span><br><span class="line"><span class="meta">@WebServlet(&quot;/Demo8&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RequestDemo8</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doPost</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;demo8被访问了..&quot;</span>);</span><br><span class="line">        <span class="comment">//存储数据到request域中</span></span><br><span class="line">        request.setAttribute(<span class="string">&quot;msg&quot;</span>,<span class="string">&quot;hello&quot;</span>);</span><br><span class="line">        request.getRequestDispatcher(<span class="string">&quot;/Demo9&quot;</span>).forward(request,response);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doGet</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        doPost(request,response);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="meta">@WebServlet(&quot;/Demo9&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RequestDemo9</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doPost</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//获取数据</span></span><br><span class="line">        Object msg = request.getAttribute(<span class="string">&quot;msg&quot;</span>);</span><br><span class="line">        System.out.println(msg);</span><br><span class="line">        System.out.println(<span class="string">&quot;demo9被访问了..&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doGet</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        doPost(request,response);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
<li><p>获取ServletContext：</p>
<ol>
<li>```java<br>ServletContext servletContext = request.getServletContext();<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">## 案例：用户登录</span><br><span class="line"></span><br><span class="line">		1. 编写login.html登录页面 username&amp;password两个输入框</span><br><span class="line">		2. 使用Druid数据库连接池技术，操作mysql,day14数据库中user表，</span><br><span class="line">	            		3. 使用jdbcTemplate技术封装JDBC</span><br><span class="line">	        		4. 登录成功跳转到SuccessServlet展示：登陆成功，用户名，欢迎你。】</span><br><span class="line">	                  		5. 登录失败跳转到FailedServlet展示:登陆失败，用户名，密码错误。</span><br><span class="line"></span><br><span class="line">![img](file:&#x2F;&#x2F;&#x2F;D:\2418049194\Image\C2C\8C0ECA5ACF309F01A1B92ADF6DE60FF7.jpg)</span><br><span class="line"></span><br><span class="line">## HTTP</span><br><span class="line"></span><br><span class="line">1请求消息：客户端发送给服务器的数据</span><br><span class="line">		数据格式</span><br><span class="line"></span><br><span class="line">				1. 请求行</span><br><span class="line">				2. 请求头</span><br><span class="line">	                    				3. 请求空行</span><br><span class="line">	              				4. 请求体</span><br><span class="line"></span><br><span class="line">2响应消息：服务器发送给客户端的数据</span><br><span class="line"></span><br><span class="line">数据格式</span><br><span class="line"></span><br><span class="line"> 1. 响应行</span><br><span class="line"></span><br><span class="line">     1. 组成：协议&#x2F;版本  响应状态码 状态码描述</span><br><span class="line"></span><br><span class="line">     2. 响应状态码：服务器告诉客户端浏览器本次请求和响应的状态</span><br><span class="line"></span><br><span class="line">     3. 状态码三位数字，分五类</span><br><span class="line"></span><br><span class="line">         1. ​	分类</span><br><span class="line"></span><br><span class="line">             1. 1xx:客户端接收客户端消息，但没有接收完成，等待一段时间后，发送1xx状态码</span><br><span class="line"></span><br><span class="line">             2. 2xx：成功</span><br><span class="line"></span><br><span class="line">             3. 3xx：重定向 代表302（重定向），304（访问缓存）</span><br><span class="line"></span><br><span class="line">             4. 4xx：客户端错误，代表404（代表请求路径没有对应资源）</span><br><span class="line"></span><br><span class="line">                ​										405（请求的方式没有对应的do方法）</span><br><span class="line"></span><br><span class="line">             5. 5xx：服务器端错误，代表500，服务器内部出现异常</span><br><span class="line"></span><br><span class="line">            </span><br><span class="line"></span><br><span class="line"> 2. 响应头</span><br><span class="line"></span><br><span class="line">     1. 格式：头名称：值</span><br><span class="line"></span><br><span class="line">     2. 常见象响应头“</span><br><span class="line"></span><br><span class="line">        ​	Content-Type:服务器告诉客户端本次响应数据格式以及编码格式</span><br><span class="line"></span><br><span class="line">        ​		Content-Type: text&#x2F;html;charset&#x3D;utf-8</span><br><span class="line"></span><br><span class="line">        ​	Content-disposition:服务器告诉客户端以说什么格式打开响应体数据</span><br><span class="line">        ​					值：</span><br><span class="line"></span><br><span class="line">        ​								in-line:默认值，在当前页面打开。</span><br><span class="line"></span><br><span class="line">        ​								attchment:filename&#x3D;xxx,以附件形式打开响应体。文件下载</span><br><span class="line"></span><br><span class="line">        ​	</span><br><span class="line"></span><br><span class="line"> 3. 响应空行</span><br><span class="line"></span><br><span class="line"> 4. 响应体：真实的传输数据</span><br><span class="line"></span><br><span class="line">     	1. 数据</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">响应字符串格式：</span><br><span class="line"></span><br><span class="line">	HTTP&#x2F;1.1 200 OK--》响应行</span><br></pre></td></tr></table></figure>
Bdpagetype: 1<br>Bdqid: 0xd433a9c00000d526<br>Cache-Control: private<br>Connection: keep-alive<br>Content-Encoding: gzip<br>Content-Type: text/html;charset=utf-8<br>Date: Thu, 08 Oct 2020 10:10:57 GMT<br>Expires: Thu, 08 Oct 2020 10:10:57 GMT<br>Server: BWS/1.1<br>Set-Cookie: BDSVRTM=16; path=/<br>Set-Cookie: BD_HOME=1; path=/<br>Set-Cookie: H_PS_PSSID=32812_32617_1467_32793_7566_31253_32705_32231_7516_32117_32719_22160; path=/; domain=.baidu.com<br>Strict-Transport-Security: max-age=172800<br>Traceid: 1602151857027174145015290751801951835430<br>X-Ua-Compatible: IE=Edge,chrome=1<br>Transfer-Encoding: chunked</li>
</ol>
</li>
</ol>
</li>
</ol>
<p>响应体《HTML》<br>。。。。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## Response</span><br><span class="line"></span><br><span class="line">   	功能：设置响应消息</span><br><span class="line"></span><br><span class="line">  1. 设置响应行</span><br><span class="line">     	格式：HTTP&#x2F;1.1 200 ok</span><br><span class="line"></span><br><span class="line">     ​	设置状态码：setStatus(int sc)</span><br><span class="line"></span><br><span class="line">  2. 设置响应头：setHeader(String name,String value);</span><br><span class="line"></span><br><span class="line">     ​	</span><br><span class="line"></span><br><span class="line">  3. 设置响应体:</span><br><span class="line"></span><br><span class="line">       		1. ​	使用步骤：</span><br><span class="line">              	   		1. 获取输出流</span><br><span class="line">              	          		1. 字符输出流：PrintWriter getWriter()</span><br><span class="line">              	          		2. 字节输出流：ServletOutputStream getOutputStream()</span><br><span class="line">              	   		2. 使用输出流，将数据输出到客户端浏览器</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">案例：</span><br><span class="line"></span><br><span class="line">1. 完成重定向：![img](file:&#x2F;&#x2F;&#x2F;D:\2418049194\Image\C2C\8D3BBCE39EC6EA1BECBB3ECDDC5BE821.jpg)</span><br><span class="line"></span><br><span class="line">   1. &#96;&#96;&#96;java</span><br><span class="line">      重定向:资源跳转方式</span><br><span class="line">      @Override</span><br><span class="line">      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException &#123;</span><br><span class="line">          System.out.println(&quot;demo1...&quot;);</span><br><span class="line">          &#x2F;&#x2F;访问responseDemo1会自定跳转到responseDemo2</span><br><span class="line">          &#x2F;&#x2F;1设置状态码为303</span><br><span class="line">       &#x2F;&#x2F;   resp.setStatus(302);</span><br><span class="line">          &#x2F;&#x2F;设置响应头为Location</span><br><span class="line">       &#x2F;&#x2F;   resp.setHeader(&quot;location&quot;,&quot;&#x2F;day15&#x2F;Demo2&quot;);</span><br><span class="line">      </span><br><span class="line">          &#x2F;&#x2F;简单的重定向方法</span><br><span class="line">          resp.sendRedirect(&quot;&#x2F;day15&#x2F;Demo2&quot;);</span><br><span class="line">      &#125;</span><br></pre></td></tr></table></figure>

<pre><code>  （redirect）重定向的特点：

      1. 地址栏发生变化
      2. 重定向可以访问其他站点（服务器）的资源        
      3. ==重定向是两次请求==,有两个request对象

  (forward)转发的特点：

          1. 转发地址不变
          2. 转发只能访问当前服务器下的资源
                          3. 转发是一次请求,可以使用request对象共享数据

  路径写法：

    1. 路径分类：

         1. 相对路径：通过相对路径不可以获得唯一的资源

            ​    **如        ./index.html**   ./表示当前目录下

            ​    **不以   /  开头的以   .   开头的路径**

            ​    

            规则：找到的当前资源和目标资源之间的相对位置关系

            ​            ./当前目录

            ​            ../后退一级目录

         2. 绝对路径：通过绝对路径可以确定唯一资源（推荐：不要确定关系）

                      1. 如：http://localhost/day15/Demo1
                                    2. /day15/Demo1(省略协议，域名端口号，以**“/”**开头的路径http://localhost)
                                3. **以      /   ** 开头的路径是绝对路径

            绝对路径规则：判断定义的路径给谁用？判断请求从哪发出

               1. 给客户端浏览器用：需要加虚拟目录（项目的访问路径:  /day15/demo2）
                          重定向需要加虚拟目录
                                客户端的虚拟目录建议虚拟目录动态获取    

                  ​        ：String contextPath=request.getContextPath();    

               2. 给服务器使用：不需要加虚拟目录(                                             /demo2)

                  ​        转发路径是服务端用的，不要虚拟目录
</code></pre>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">	动态获取虚拟目录“</span><br><span class="line">String contextPath=request.getContextPath();						response.sendRedirect(contextPath+<span class="string">&quot;/Demo2&quot;</span>);</span><br></pre></td></tr></table></figure>



<ol>
<li><p>服务器输出字符数据到浏览器</p>
<ol>
<li><p>步骤：</p>
<ol>
<li><p>获取字符输出流</p>
</li>
<li><p>输出数据</p>
</li>
<li><p>```java<br> //获取字符输出流<br> PrintWriter pw=resp.getWriter();<br> //输出数据<br>// pw.write(“hello,response”);<br> pw.write(“<h1> hello,response</h1>“);</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">中文乱码：</span><br><span class="line"></span><br><span class="line">​		</span><br><span class="line"></span><br><span class="line">&#96;&#96;&#96;java</span><br><span class="line">@WebServlet(&quot;&#x2F;Demo4&quot;)</span><br><span class="line">public class Demo4 extends HttpServlet &#123;</span><br><span class="line">    @Override</span><br><span class="line">    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException &#123;</span><br><span class="line"></span><br><span class="line">        &#x2F;&#x2F;获取对象之前，设置流的默认编码：ISO-8859-1设置为GBK</span><br><span class="line">    	&#x2F;&#x2F;    resp.setCharacterEncoding(&quot;UTF-8&quot;);</span><br><span class="line">        </span><br><span class="line">        </span><br><span class="line">        </span><br><span class="line">        &#x2F;&#x2F;告诉浏览器，服务器发送的消息体数据的编码，建议浏览器使用该编码解码  </span><br><span class="line">        &#x2F;&#x2F;在获取流之前设置</span><br><span class="line">        resp.setHeader(&quot;content-type&quot;,&quot;text&#x2F;html;charset&#x3D;utf-8&quot;);</span><br><span class="line"></span><br><span class="line">        &#x2F;&#x2F;获取字符输出流</span><br><span class="line">        PrintWriter pw&#x3D;resp.getWriter();</span><br><span class="line">        &#x2F;&#x2F;输出数据</span><br><span class="line">       &#x2F;&#x2F; pw.write(&quot;hello,response&quot;);</span><br><span class="line">        pw.write(&quot;&lt;h1&gt; 你好&lt;&#x2F;h1&gt;&quot;);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException &#123;</span><br><span class="line">       this.doPost(req,resp);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//简单的形式，设置编码，在获取流之前设置</span></span><br><span class="line">resp.setContentType(<span class="string">&quot;text/html;charset=utf-8&quot;</span>);</span><br></pre></td></tr></table></figure></li>
</ol>
</li>
</ol>
</li>
<li><p>服务器输出字节数据到浏览器</p>
<ol>
<li>```java<br>@WebServlet(“/Demo5”)<br>public class Demo5 extends HttpServlet {<pre><code>@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException &#123;
    resp.setContentType(&quot;text/html;charset=utf-8&quot;);
    //获取字节输出流
    ServletOutputStream sos=resp.getOutputStream();
    //输出数据
    sos.write(&quot;hell年少的o&quot;.getBytes(&quot;utf-8&quot;));
&#125;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException &#123;
   this.doPost(req,resp);
&#125;
</code></pre>
}<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">3. 验证码</span><br><span class="line"></span><br><span class="line">   ​		本质：是图片</span><br><span class="line"></span><br><span class="line">   ​		目的：防止恶意表单注册</span><br><span class="line"></span><br><span class="line">   ​		</span><br><span class="line"></span><br><span class="line">   ​	</span><br><span class="line"></span><br><span class="line">   &#96;&#96;&#96;java</span><br><span class="line">   package servlet;</span><br><span class="line">   </span><br><span class="line">   import javax.imageio.ImageIO;</span><br><span class="line">   import javax.servlet.ServletException;</span><br><span class="line">   import javax.servlet.annotation.WebServlet;</span><br><span class="line">   import javax.servlet.http.HttpServlet;</span><br><span class="line">   import javax.servlet.http.HttpServletRequest;</span><br><span class="line">   import javax.servlet.http.HttpServletResponse;</span><br><span class="line">   import java.awt.*;</span><br><span class="line">   import java.awt.image.BufferedImage;</span><br><span class="line">   import java.io.IOException;</span><br><span class="line">   import java.util.Random;</span><br><span class="line">   </span><br><span class="line">   &#x2F;**</span><br><span class="line">    *</span><br><span class="line">    *&#x2F;</span><br><span class="line">   @WebServlet(&quot;&#x2F;checkCodeServlet&quot;)</span><br><span class="line">   public class CheckCodeServlet extends HttpServlet &#123;</span><br><span class="line">       protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException &#123;</span><br><span class="line">   </span><br><span class="line">           int width&#x3D;100;</span><br><span class="line">           int height&#x3D;50;</span><br><span class="line">   </span><br><span class="line">           &#x2F;&#x2F;1.创建一个对象在内存中代表图片（验证码图片对象）</span><br><span class="line">           BufferedImage image&#x3D;new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);</span><br><span class="line">   </span><br><span class="line">   </span><br><span class="line">           &#x2F;&#x2F;2，美化图片</span><br><span class="line">               &#x2F;&#x2F;2.1填错背景色</span><br><span class="line">           Graphics g &#x3D; image.getGraphics();&#x2F;&#x2F;画笔对象</span><br><span class="line">           g.setColor(Color.pink);</span><br><span class="line">           g.fillRect(0,0,width,height);</span><br><span class="line">               &#x2F;&#x2F;2.2画边框</span><br><span class="line">           g.setColor(Color.blue);</span><br><span class="line">           g.drawRect(0,0,width-1,height-1);</span><br><span class="line">               &#x2F;&#x2F;2.3写验证码</span><br><span class="line">           String str&#x3D;&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789&quot;;</span><br><span class="line">               &#x2F;&#x2F;生成随机角标</span><br><span class="line">           Random ran&#x3D;new Random();</span><br><span class="line">           for (int i &#x3D; 1; i &lt;&#x3D;4 ; i++) &#123;</span><br><span class="line">               int index &#x3D; ran.nextInt(str.length());</span><br><span class="line">               &#x2F;&#x2F;获取字符</span><br><span class="line">               char ch &#x3D; str.charAt(index);</span><br><span class="line">               g.drawString(ch+&quot;&quot;,width&#x2F;5*i,height&#x2F;2);</span><br><span class="line">           &#125;</span><br><span class="line">   </span><br><span class="line">           &#x2F;&#x2F;2.4画干扰线</span><br><span class="line">           for (int i &#x3D; 0; i &lt;10 ; i++) &#123;</span><br><span class="line">               int x1&#x3D;ran.nextInt(width);</span><br><span class="line">               int x2&#x3D;ran.nextInt(width);</span><br><span class="line">               int y1&#x3D;ran.nextInt(height);</span><br><span class="line">               int y2&#x3D;ran.nextInt(height);</span><br><span class="line">               g.setColor(Color.green);</span><br><span class="line">               g.drawLine(x1,y1,x2,y2);</span><br><span class="line">           &#125;</span><br><span class="line">   </span><br><span class="line">           &#x2F;&#x2F;3.将图片输出到页面展示</span><br><span class="line">           ImageIO.write(image,&quot;jpg&quot;,response.getOutputStream());</span><br><span class="line">       &#125;</span><br><span class="line">   </span><br><span class="line">       protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException &#123;</span><br><span class="line">           this.doPost(request, response);</span><br><span class="line">       &#125;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure></li>
</ol>
<p>–</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Title<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span>&gt;</span></span><br><span class="line">        /*</span><br><span class="line">            分析</span><br><span class="line">                点击超链接或者图片，换一张</span><br><span class="line">                1.给超链接和图片绑定单击事件</span><br><span class="line"></span><br><span class="line">                2.重新设置图片的src属性</span><br><span class="line">         */</span><br><span class="line"><span class="javascript">        <span class="built_in">window</span>.onload=<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span></span><br><span class="line"><span class="javascript">            <span class="comment">//1.获取图片对象</span></span></span><br><span class="line"><span class="javascript">            <span class="keyword">var</span> img = <span class="built_in">document</span>.getElementById(<span class="string">&quot;checkCode&quot;</span>);</span></span><br><span class="line"><span class="javascript">            <span class="comment">//2.绑定单击事件</span></span></span><br><span class="line"><span class="javascript">            img.onclick=<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span></span><br><span class="line"><span class="javascript">                <span class="comment">//加时间戳</span></span></span><br><span class="line"><span class="javascript">                <span class="keyword">var</span> date=<span class="keyword">new</span> <span class="built_in">Date</span>().getTime();</span></span><br><span class="line"><span class="javascript">                img.src=<span class="string">&quot;/day16/checkCodeServlet?&quot;</span>+date;</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">img</span> <span class="attr">id</span>=<span class="string">&quot;checkCode&quot;</span> <span class="attr">src</span>=<span class="string">&quot;/day16/checkCodeServlet&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">&quot;&quot;</span>&gt;</span>看不清换一张.<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br><span class="line">​```html</span><br></pre></td></tr></table></figure>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title></li>
</ol>
<hr>
<h2 id="ServletContext对象"><a href="#ServletContext对象" class="headerlink" title="ServletContext对象"></a>ServletContext对象</h2><ol>
<li>概念：代表整个web应用，可以和程序的容器（服务器）来通信。</li>
<li>获取：<ol>
<li><p>通过request对象获取：</p>
<p>request.getServletContext();</p>
</li>
<li><p>通过HttpServlet获取：</p>
<pre><code>this.getServletContext();
</code></pre>
</li>
</ol>
</li>
<li>功能：<ol>
<li><p>获取MIME类型：</p>
<ol>
<li><p>MIME类型:在互联网通信过程中定义的一种文件数据类型</p>
<ol>
<li>格式：大类型/小类型     text/html       image/jpeg</li>
</ol>
</li>
<li><p>获取：String getMineType (String File)</p>
<p>​    </p>
</li>
</ol>
</li>
</ol>
</li>
</ol>
   <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">  &#x2F;&#x2F; 1. 通过request对象获取：</span><br><span class="line">   ServletContext context1 &#x3D; req.getServletContext();</span><br><span class="line">   System.out.println(context1);</span><br><span class="line">   &#x2F;&#x2F;2. 通过HttpServlet获取：</span><br><span class="line">   ServletContext context2 &#x3D; this.getServletContext();</span><br><span class="line">   System.out.println(context2);</span><br><span class="line">System.out.println(context1&#x3D;&#x3D;context2);</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">      1.获取MIME类型：</span></span><br><span class="line"><span class="comment">            MIME类型：在互联网通信过程中定义的一种文件数据类型</span></span><br><span class="line"><span class="comment">                格式：大类型/小类型  text/html   image/jpeg</span></span><br><span class="line"><span class="comment">      </span></span><br><span class="line"><span class="comment">            获取：String getMimeType(String file)</span></span><br><span class="line"><span class="comment">               1.域对象：共享数据</span></span><br><span class="line"><span class="comment">               2. 获取文件的真实（服务器）路径</span></span><br><span class="line"><span class="comment">       */</span></span><br><span class="line">        <span class="comment">//2.通过HttpServlet获取</span></span><br><span class="line">        ServletContext context = <span class="keyword">this</span>.getServletContext();</span><br><span class="line">        <span class="comment">//3.定义文件名称</span></span><br><span class="line">        String fileName = <span class="string">&quot;a.jpg&quot;</span>;</span><br><span class="line">        <span class="comment">//4.获取MIME类型</span></span><br><span class="line">        String mineType = context.getMimeType(fileName);</span><br><span class="line">       System.out.println(mineType);</span><br><span class="line">      ```</span><br><span class="line"></span><br><span class="line"><span class="number">2.</span> 域对象：共享数据，（set.attribute,get.attribute）</span><br><span class="line"></span><br><span class="line">   <span class="number">1.</span> ```</span><br><span class="line">      setAttribute(String name,Object value);</span><br><span class="line">      getAttribute(String name);</span><br><span class="line">   removeAttribute(String name);</span><br><span class="line">      ```</span><br><span class="line"></span><br><span class="line">      ServletContext对象作用范围：所有用户所有请求的数据</span><br><span class="line"></span><br><span class="line"><span class="number">3.</span> 获取文件的真实（服务器）路径：</span><br><span class="line"></span><br><span class="line">   <span class="number">1.</span> 方法：<span class="function">String <span class="title">getRealPath</span><span class="params">(String path)</span></span></span><br></pre></td></tr></table></figure>

<hr>
<p>​      </p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">     1.获取MIME类型：</span></span><br><span class="line"><span class="comment">              1.域对象：共享数据</span></span><br><span class="line"><span class="comment">              2. 获取文件的真实（服务器）路径</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line">       <span class="comment">//2.通过HttpServlet获取</span></span><br><span class="line">       ServletContext context = <span class="keyword">this</span>.getServletContext();</span><br><span class="line">       <span class="comment">//获取文件服务器路径：</span></span><br><span class="line">       String realPath = context.getRealPath(<span class="string">&quot;/b.txt&quot;</span>);<span class="comment">//web目录下资源目录</span></span><br><span class="line">      <span class="comment">// File file=new File(realPath);</span></span><br><span class="line">      <span class="comment">// System.out.println(realPath);</span></span><br><span class="line">       String c = context.getRealPath(<span class="string">&quot;/WEB-INF/c.txt&quot;</span>);<span class="comment">//WEB-INF下的资源访问</span></span><br><span class="line">       System.out.println(c);</span><br><span class="line">       <span class="comment">//</span></span><br><span class="line">       String a = context.getRealPath(<span class="string">&quot;/WEB-INF/classes/a.txt&quot;</span>);<span class="comment">//src目录下的资源访问</span></span><br><span class="line">       System.out.println(a);</span><br><span class="line">        <span class="comment">//classloader可以访问src下的资源，不能获取web下的资源</span></span><br></pre></td></tr></table></figure>

<hr>
<pre><code>### 案例
   
     文件下载：
     
               1. 页面显示超链接
        2. 点击超链接后弹出下载提示框
                   3. 完成图片文件下载
   
     分析：
     
         1. 超链接指向的资源能够被浏览器解析，则在浏览器中展示，如果不能解析，则弹出下载提示框
          2. 任何资源都必须弹出下载提示框
               1. 使用响应头设置资源的打开方式：
                    1. content-disposition:attachment;filename=xxx
         3. 步骤：
                 1. 定义页面，编辑超连接，指向Servlet，传递资源的名称filename
                     2. 定义Servlet
                 1. 获取要下载文件名称
                 2. 使用字节输入流加载文件进内存(需要文件真实路径：servletcontext获取)
              3. 指定response的响应头：content-disposition:attachment;filename=xxx
                 4. 将数据写出到response输出流
</code></pre>
<hr>
   <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> cn.cast.DownloadServlet;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> cn.cast.utils.DownLoadUtils;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.servlet.ServletContext;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.ServletException;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.ServletOutputStream;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.annotation.WebServlet;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServlet;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletRequest;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletResponse;</span><br><span class="line"><span class="keyword">import</span> java.io.FileInputStream;</span><br><span class="line"><span class="keyword">import</span> java.io.FileNotFoundException;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@WebServlet(&quot;/downloadservlet&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DownloadServlet</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doPost</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException, FileNotFoundException </span>&#123;</span><br><span class="line">        <span class="comment">//1.获取请求参数（文件名称）</span></span><br><span class="line">        String filename = request.getParameter(<span class="string">&quot;filename&quot;</span>);</span><br><span class="line">        <span class="comment">//2.使用字节输入流加载文件进内存</span></span><br><span class="line">        <span class="comment">//2.1找到文件的服务器路径</span></span><br><span class="line">        ServletContext servletContext = <span class="keyword">this</span>.getServletContext();</span><br><span class="line">        String realPath = ((ServletContext) servletContext).getRealPath(<span class="string">&quot;/img/&quot;</span> + filename);</span><br><span class="line">        <span class="comment">//2.2用字节流关联</span></span><br><span class="line">        FileInputStream fis=<span class="keyword">new</span> FileInputStream(realPath);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//3.设置response的响应头</span></span><br><span class="line">        <span class="comment">//3.1设置头文件：content-type</span></span><br><span class="line">        String mimeType = servletContext.getMimeType(filename);<span class="comment">//获取文件的MIME类型</span></span><br><span class="line">        response.setHeader(<span class="string">&quot;content-type&quot;</span>,mimeType);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//3.2设置响应头打开方式</span></span><br><span class="line"></span><br><span class="line">            <span class="comment">//解决中文文件名问题</span></span><br><span class="line">            <span class="comment">//1.获取user-agent请求头</span></span><br><span class="line">            String agent=request.getHeader(<span class="string">&quot;user-agent&quot;</span>);</span><br><span class="line">            <span class="comment">//2.使用工具类方法编码文件名即可</span></span><br><span class="line">             filename = DownLoadUtils.getFileName(agent,filename);</span><br><span class="line">            response.setHeader(<span class="string">&quot;content-disposition&quot;</span>,<span class="string">&quot;attachment;filename=&quot;</span>+filename);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//4将输入流的数据写出到输出流当中</span></span><br><span class="line">        ServletOutputStream sos = response.getOutputStream();</span><br><span class="line">        <span class="keyword">byte</span>[] buff=<span class="keyword">new</span> <span class="keyword">byte</span>[<span class="number">1024</span>*<span class="number">8</span>];</span><br><span class="line">        <span class="keyword">int</span> len=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>((len=fis.read(buff))!=-<span class="number">1</span>)&#123;</span><br><span class="line">            sos.write(buff,<span class="number">0</span>,len);</span><br><span class="line">        &#125;</span><br><span class="line">        fis.close();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doGet</span><span class="params">(HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.doPost(request,response);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

   <figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&lt;!DOCTYPE html&gt;</span><br><span class="line">&lt;html lang=<span class="string">&quot;en&quot;</span>&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">    &lt;meta charset=<span class="string">&quot;UTF-8&quot;</span>&gt;</span><br><span class="line">    &lt;title&gt;Title&lt;/title&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">    <span class="comment">//&lt;a href=&quot;/day15/img/1.jpg&quot;&gt;图片&lt;/a&gt;</span></span><br><span class="line">    &lt;hr&gt;</span><br><span class="line">    &lt;a href=&quot;/day15/downloadservlet?filename=1.jpg&quot;&gt;图片1&lt;/a&gt;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">WEB</span><br><span class="line">	img</span><br><span class="line">		1.jpg</span><br><span class="line">	dowmload.html</span><br></pre></td></tr></table></figure>

<p>问题，中文文件名</p>
<p>​    解决思路：</p>
<p>找个工具类DownloadUtils,并在项目同级目录建个utils包放进去</p>
<pre><code>        1. 获取客户端使用浏览器版本信息

        2. 根据不同版本信息，设置filename的编码方式不同
</code></pre>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/zhu/tags/%E7%BD%91%E7%BB%9C/" rel="tag"># 网络</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/zhu/2021-04-04/hello-world/" rel="next" title="Hello World">
                <i class="fa fa-chevron-left"></i> Hello World
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/zhu/2021-04-18/redis/" rel="prev" title="redis(1)">
                redis(1) <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name"></p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/zhu/archives/">
              
                  <span class="site-state-item-count">6</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/zhu/categories/index.html">
                  <span class="site-state-item-count">1</span>
                  <span class="site-state-item-name">分类</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/zhu/tags/index.html">
                  <span class="site-state-item-count">4</span>
                  <span class="site-state-item-name">标签</span>
                </a>
              </div>
            

          </nav>

          

          

          
          

          
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link"><span class="nav-number">1.</span> <span class="nav-text"></span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#HTTP%E5%8D%8F%E8%AE%AE"><span class="nav-number"></span> <span class="nav-text">HTTP协议</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#http%E5%8D%8F%E8%AE%AE%E7%AE%80%E4%BB%8B%EF%BC%9A"><span class="nav-number">0.0.1.</span> <span class="nav-text">http协议简介：</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Http%E5%8D%8F%E8%AE%AE"><span class="nav-number">0.1.</span> <span class="nav-text">Http协议</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#http%E5%93%8D%E5%BA%94%E6%8A%A5%E6%96%87%E7%9A%84%E7%BB%84%E6%88%90"><span class="nav-number">0.2.</span> <span class="nav-text">http响应报文的组成</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%B8%B8%E8%A7%81%E7%9A%84%E5%93%8D%E5%BA%94%E5%A4%B4%E5%B1%9E%E6%80%A7"><span class="nav-number">0.3.</span> <span class="nav-text">常见的响应头属性</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#ServletRequest%E4%B8%AD%E6%96%87%E7%9A%84%E5%93%8D%E5%BA%94%E4%B9%B1%E7%A0%81"><span class="nav-number">1.</span> <span class="nav-text">ServletRequest中文的响应乱码</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%87%8D%E5%AE%9A%E5%90%91"><span class="nav-number">2.</span> <span class="nav-text">重定向</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#HTTP"><span class="nav-number"></span> <span class="nav-text">HTTP</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#Request%EF%BC%9A"><span class="nav-number">1.</span> <span class="nav-text">Request：</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link"><span class="nav-number"></span> <span class="nav-text"> hello,response</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#ServletContext%E5%AF%B9%E8%B1%A1"><span class="nav-number">1.</span> <span class="nav-text">ServletContext对象</span></a></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2021</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">zhu</span>

  
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-area-chart"></i>
    </span>
    
      <span class="post-meta-item-text">Site words total count&#58;</span>
    
    <span title="Site words total count">25.1k</span>
  
</div>


  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Pisces</a> v5.1.4</div>






<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>





        
<div class="busuanzi-count">
 
<script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>


  
    <span class="site-uv">
      踩过的小伙伴
      <span class="busuanzi-value" id="busuanzi_value_site_uv"></span>
      
    </span>
  

  
    <span class="site-pv">
      本站访问量
      <span class="busuanzi-value" id="busuanzi_value_site_pv"></span>
      
    </span>
  
</div>








        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/zhu/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/zhu/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/zhu/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/zhu/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/zhu/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/zhu/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/zhu/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/zhu/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/zhu/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/zhu/js/src/schemes/pisces.js?v=5.1.4"></script>



  
  <script type="text/javascript" src="/zhu/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/zhu/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/zhu/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  

  <script type="text/javascript">
    // Popup Window;
    var isfetched = false;
    var isXml = true;
    // Search DB path;
    var search_path = "./public/search.xml";
    if (search_path.length === 0) {
      search_path = "search.xml";
    } else if (/json$/i.test(search_path)) {
      isXml = false;
    }
    var path = "/zhu/" + search_path;
    // monitor main search box;

    var onPopupClose = function (e) {
      $('.popup').hide();
      $('#local-search-input').val('');
      $('.search-result-list').remove();
      $('#no-result').remove();
      $(".local-search-pop-overlay").remove();
      $('body').css('overflow', '');
    }

    function proceedsearch() {
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay"></div>')
        .css('overflow', 'hidden');
      $('.search-popup-overlay').click(onPopupClose);
      $('.popup').toggle();
      var $localSearchInput = $('#local-search-input');
      $localSearchInput.attr("autocapitalize", "none");
      $localSearchInput.attr("autocorrect", "off");
      $localSearchInput.focus();
    }

    // search function;
    var searchFunc = function(path, search_id, content_id) {
      'use strict';

      // start loading animation
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay">' +
          '<div id="search-loading-icon">' +
          '<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +
          '</div>' +
          '</div>')
        .css('overflow', 'hidden');
      $("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');

      $.ajax({
        url: path,
        dataType: isXml ? "xml" : "json",
        async: true,
        success: function(res) {
          // get the contents from search data
          isfetched = true;
          $('.popup').detach().appendTo('.header-inner');
          var datas = isXml ? $("entry", res).map(function() {
            return {
              title: $("title", this).text(),
              content: $("content",this).text(),
              url: $("url" , this).text()
            };
          }).get() : res;
          var input = document.getElementById(search_id);
          var resultContent = document.getElementById(content_id);
          var inputEventFunction = function() {
            var searchText = input.value.trim().toLowerCase();
            var keywords = searchText.split(/[\s\-]+/);
            if (keywords.length > 1) {
              keywords.push(searchText);
            }
            var resultItems = [];
            if (searchText.length > 0) {
              // perform local searching
              datas.forEach(function(data) {
                var isMatch = false;
                var hitCount = 0;
                var searchTextCount = 0;
                var title = data.title.trim();
                var titleInLowerCase = title.toLowerCase();
                var content = data.content.trim().replace(/<[^>]+>/g,"");
                var contentInLowerCase = content.toLowerCase();
                var articleUrl = decodeURIComponent(data.url);
                var indexOfTitle = [];
                var indexOfContent = [];
                // only match articles with not empty titles
                if(title != '') {
                  keywords.forEach(function(keyword) {
                    function getIndexByWord(word, text, caseSensitive) {
                      var wordLen = word.length;
                      if (wordLen === 0) {
                        return [];
                      }
                      var startPosition = 0, position = [], index = [];
                      if (!caseSensitive) {
                        text = text.toLowerCase();
                        word = word.toLowerCase();
                      }
                      while ((position = text.indexOf(word, startPosition)) > -1) {
                        index.push({position: position, word: word});
                        startPosition = position + wordLen;
                      }
                      return index;
                    }

                    indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
                    indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
                  });
                  if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
                    isMatch = true;
                    hitCount = indexOfTitle.length + indexOfContent.length;
                  }
                }

                // show search results

                if (isMatch) {
                  // sort index by position of keyword

                  [indexOfTitle, indexOfContent].forEach(function (index) {
                    index.sort(function (itemLeft, itemRight) {
                      if (itemRight.position !== itemLeft.position) {
                        return itemRight.position - itemLeft.position;
                      } else {
                        return itemLeft.word.length - itemRight.word.length;
                      }
                    });
                  });

                  // merge hits into slices

                  function mergeIntoSlice(text, start, end, index) {
                    var item = index[index.length - 1];
                    var position = item.position;
                    var word = item.word;
                    var hits = [];
                    var searchTextCountInSlice = 0;
                    while (position + word.length <= end && index.length != 0) {
                      if (word === searchText) {
                        searchTextCountInSlice++;
                      }
                      hits.push({position: position, length: word.length});
                      var wordEnd = position + word.length;

                      // move to next position of hit

                      index.pop();
                      while (index.length != 0) {
                        item = index[index.length - 1];
                        position = item.position;
                        word = item.word;
                        if (wordEnd > position) {
                          index.pop();
                        } else {
                          break;
                        }
                      }
                    }
                    searchTextCount += searchTextCountInSlice;
                    return {
                      hits: hits,
                      start: start,
                      end: end,
                      searchTextCount: searchTextCountInSlice
                    };
                  }

                  var slicesOfTitle = [];
                  if (indexOfTitle.length != 0) {
                    slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
                  }

                  var slicesOfContent = [];
                  while (indexOfContent.length != 0) {
                    var item = indexOfContent[indexOfContent.length - 1];
                    var position = item.position;
                    var word = item.word;
                    // cut out 100 characters
                    var start = position - 20;
                    var end = position + 80;
                    if(start < 0){
                      start = 0;
                    }
                    if (end < position + word.length) {
                      end = position + word.length;
                    }
                    if(end > content.length){
                      end = content.length;
                    }
                    slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
                  }

                  // sort slices in content by search text's count and hits' count

                  slicesOfContent.sort(function (sliceLeft, sliceRight) {
                    if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
                      return sliceRight.searchTextCount - sliceLeft.searchTextCount;
                    } else if (sliceLeft.hits.length !== sliceRight.hits.length) {
                      return sliceRight.hits.length - sliceLeft.hits.length;
                    } else {
                      return sliceLeft.start - sliceRight.start;
                    }
                  });

                  // select top N slices in content

                  var upperBound = parseInt('-1');
                  if (upperBound >= 0) {
                    slicesOfContent = slicesOfContent.slice(0, upperBound);
                  }

                  // highlight title and content

                  function highlightKeyword(text, slice) {
                    var result = '';
                    var prevEnd = slice.start;
                    slice.hits.forEach(function (hit) {
                      result += text.substring(prevEnd, hit.position);
                      var end = hit.position + hit.length;
                      result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
                      prevEnd = end;
                    });
                    result += text.substring(prevEnd, slice.end);
                    return result;
                  }

                  var resultItem = '';

                  if (slicesOfTitle.length != 0) {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";
                  } else {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";
                  }

                  slicesOfContent.forEach(function (slice) {
                    resultItem += "<a href='" + articleUrl + "'>" +
                      "<p class=\"search-result\">" + highlightKeyword(content, slice) +
                      "...</p>" + "</a>";
                  });

                  resultItem += "</li>";
                  resultItems.push({
                    item: resultItem,
                    searchTextCount: searchTextCount,
                    hitCount: hitCount,
                    id: resultItems.length
                  });
                }
              })
            };
            if (keywords.length === 1 && keywords[0] === "") {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'
            } else if (resultItems.length === 0) {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'
            } else {
              resultItems.sort(function (resultLeft, resultRight) {
                if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
                  return resultRight.searchTextCount - resultLeft.searchTextCount;
                } else if (resultLeft.hitCount !== resultRight.hitCount) {
                  return resultRight.hitCount - resultLeft.hitCount;
                } else {
                  return resultRight.id - resultLeft.id;
                }
              });
              var searchResultList = '<ul class=\"search-result-list\">';
              resultItems.forEach(function (result) {
                searchResultList += result.item;
              })
              searchResultList += "</ul>";
              resultContent.innerHTML = searchResultList;
            }
          }

          if ('auto' === 'auto') {
            input.addEventListener('input', inputEventFunction);
          } else {
            $('.search-icon').click(inputEventFunction);
            input.addEventListener('keypress', function (event) {
              if (event.keyCode === 13) {
                inputEventFunction();
              }
            });
          }

          // remove loading animation
          $(".local-search-pop-overlay").remove();
          $('body').css('overflow', '');

          proceedsearch();
        }
      });
    }

    // handle and trigger popup window;
    $('.popup-trigger').click(function(e) {
      e.stopPropagation();
      if (isfetched === false) {
        searchFunc(path, 'local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });

    $('.popup-btn-close').click(onPopupClose);
    $('.popup').click(function(e){
      e.stopPropagation();
    });
    $(document).on('keyup', function (event) {
      var shouldDismissSearchPopup = event.which === 27 &&
        $('.search-popup').is(':visible');
      if (shouldDismissSearchPopup) {
        onPopupClose();
      }
    });
  </script>





  

  

  

  
  

  

  

  

</body>
</html>
